package com.sky.sd.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.netflix.discovery.converters.Auto;
import com.sky.sd.system.bean.dto.BasicPair;
import com.sky.sd.system.bean.dto.BasicPairNode;
import com.sky.sd.system.bean.po.Dept;
import com.sky.sd.system.bean.po.Dic;
import com.sky.sd.system.bean.po.Menu;
import com.sky.sd.system.bean.po.Role;
import com.sky.sd.system.constant.SystemConstant;
import com.sky.sd.system.dao.DeptMapper;
import com.sky.sd.system.dao.DicMapper;
import com.sky.sd.system.dao.MenuMapper;
import com.sky.sd.system.dao.RoleMapper;
import com.sky.sd.system.enums.EnabledType;
import com.sky.sd.system.enums.MenuType;
import com.sky.sd.system.service.IBasicService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <br/>功能:
 * <br/>版本: 1.0
 * <br/>开发人员: 弓振
 * <br/>创建日期: 2020/7/3 10:45
 * <br/>修改日期: 2020/7/3 10:45
 * <br/>修改列表:
 */
@Service
@Slf4j
public class BasicServiceImpl implements IBasicService {

    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private DicMapper dicMapper;

    @Override
    public List<BasicPairNode> listDept() {
        List<Dept> depts = deptMapper.selectList(Wrappers.<Dept>lambdaQuery().eq(Dept::getEnabled, EnabledType.ENABLED).orderByAsc(Dept::getSort));

        // 转换
        List<BasicPairNode> nodes = depts.parallelStream().map(dept -> {
            return BasicPairNode.builder().parentId(dept.getParentId())
                    .label(dept.getDeptName()).value(dept.getId()).sort(dept.getSort())
                    .id(dept.getId()).build();
        }).collect(Collectors.toList());

        // 创建树
        List<BasicPairNode> topNodes = initTree(nodes);
        log.info("获取部门信息:{}",topNodes);
        return topNodes;
    }

    @Override
    public List<BasicPair> listRole() {
        List<Role> roles = roleMapper.selectList(Wrappers.<Role>lambdaQuery().eq(Role::getEnabled,EnabledType.ENABLED).orderByDesc(Role::getUpdateTime));
        List<BasicPair> basicPairs = roles.parallelStream().map(role -> {
            return BasicPair.builder().value(role.getId()).label(role.getName()).build();
        }).collect(Collectors.toList());
        return basicPairs;
    }

    @Override
    public List<BasicPair> listRoleByType(String type) {
        List<Role> roles = roleMapper.selectList(Wrappers.<Role>lambdaQuery().eq(Role::getEnabled,EnabledType.ENABLED)
                .eq(Role::getType, type).orderByDesc(Role::getUpdateTime));
        List<BasicPair> basicPairs = roles.parallelStream().map(role -> {
            return BasicPair.builder().value(role.getId()).label(role.getName()).build();
        }).collect(Collectors.toList());
        return basicPairs;
    }

    @Override
    public List<BasicPairNode> listMenu() {
        List<Menu> menus = menuMapper.selectList(Wrappers.<Menu>lambdaQuery()
                .eq(Menu::getEnabled,EnabledType.ENABLED).eq(Menu::getType, MenuType.MENU)
                .eq(Menu::getEnabled, EnabledType.ENABLED).orderByAsc(Menu::getSort));

        // 转换
        List<BasicPairNode> nodes = menus.parallelStream().map(menu -> {
            return BasicPairNode.builder().parentId(menu.getParentId())
                    .label(menu.getName()).value(menu.getId()).sort(menu.getSort())
                    .id(menu.getId()).build();
        }).collect(Collectors.toList());

        // 创建树
        List<BasicPairNode> topNodes = initTree(nodes);
        log.info("获取菜单信息:{}",topNodes);
        return topNodes;
    }

    @Override
    public List<BasicPairNode> listPermsByMenuId(String menuId) {
        List<Menu> menus = menuMapper.selectList(Wrappers.<Menu>lambdaQuery()
                .eq(Menu::getParentId, menuId).eq(Menu::getEnabled, EnabledType.ENABLED)
                .eq(Menu::getType, MenuType.BUTTON).orderByAsc(Menu::getSort));
        // 转换
        List<BasicPairNode> topNodes = menus.parallelStream().map(menu -> {
            return BasicPairNode.builder().parentId(menu.getParentId())
                    .label(menu.getName()).value(menu.getId()).sort(menu.getSort())
                    .id(menu.getId()).code(menu.getCode()).build();
        }).sorted().collect(Collectors.toList());

        // 创建树
        topNodes.parallelStream().forEach(node -> {
            postCreateTree(node.getId(),node);
        });
        log.info("根据菜单{}获取权限信息:{}",menuId,topNodes);
        return topNodes;
    }

    @Override
    public List<BasicPair> lisPDic() {
        List<Dic> dics = dicMapper.selectList(Wrappers.<Dic>lambdaQuery().eq(Dic::getParentId,SystemConstant.TOP_PARENT_ID).orderByAsc(Dic::getSort));
        List<BasicPair> basicPairs = dics.parallelStream().map(dic -> {
            return BasicPair.builder().value(dic.getId()).label(dic.getName()).build();
        }).collect(Collectors.toList());
        return basicPairs;
    }

    @Override
    public List<BasicPair> lisChildDicByCode(String code) {
        // 根据编码查询数据字典
        Optional<Dic> pDicOptional = Optional.of(dicMapper.selectOne(Wrappers.<Dic>lambdaQuery().eq(Dic::getCode, code)
                .eq(Dic::getEnabled, EnabledType.ENABLED).orderByAsc(Dic::getSort)));

        return pDicOptional.map(pDic -> {
            List<Dic> childDics = dicMapper.selectList(Wrappers.<Dic>lambdaQuery().eq(Dic::getParentId, pDic.getId())
                    .eq(Dic::getEnabled, EnabledType.ENABLED)
                    .orderByDesc(Dic::getIsDefault).orderByAsc(Dic::getSort));
            return childDics.parallelStream().map(childDic -> {
                return BasicPair.builder().value(childDic.getCode()).label(childDic.getName()).build();
            }).collect(Collectors.toList());
        }).orElse(new ArrayList<BasicPair>());
    }

    private List<BasicPairNode> initTree(List<BasicPairNode> nodes) {
        // 创建树
        List<BasicPairNode> topNodes = nodes.parallelStream()
                .filter(node -> SystemConstant.TOP_PARENT_ID.equals(node.getParentId())).collect(Collectors.toList());
        topNodes.parallelStream().forEach(node -> {
            createTree(node, nodes);
        });
        return topNodes;
    }

    private void createTree(BasicPairNode curNode, List<BasicPairNode> nodes) {
        List<BasicPairNode> nextNodes = nodes.parallelStream()
                .filter(node -> StringUtils.equals(node.getParentId(), curNode.getId()))
                .sorted().collect(Collectors.toList());
        nextNodes.parallelStream().forEach(node -> {
            createTree(node, nodes);
        });
        curNode.setChildren(nextNodes);
        curNode.setLeaf(CollectionUtils.isNotEmpty(nextNodes) ? 0 : 1);
    }

    private void postCreateTree(String menuId, BasicPairNode curNode) {
        List<Menu> menus = menuMapper.selectList(Wrappers.<Menu>lambdaQuery()
                .eq(Menu::getParentId, menuId).eq(Menu::getEnabled, EnabledType.ENABLED).eq(Menu::getType, MenuType.BUTTON));

        // 转换
        List<BasicPairNode> nextNodes = menus.parallelStream().map(menu -> {
            return BasicPairNode.builder().parentId(menu.getParentId())
                    .label(menu.getName()).value(menu.getId()).sort(menu.getSort())
                    .id(menu.getId()).code(menu.getCode()).build();
        }).sorted().collect(Collectors.toList());

        // 创建树
        nextNodes.parallelStream().forEach(node -> {
            postCreateTree(node.getId(),node);
        });

        curNode.setChildren(nextNodes);
        curNode.setLeaf(CollectionUtils.isNotEmpty(nextNodes) ? 0 : 1);
    }
}
